import sys
parent_dir = "../pygl"
sys.path.append(parent_dir)
import glfw
import OpenGL.GL as gl
import glm
import imgui
import numpy as np
from PIL import Image
from common.app_v2 import App
import pygl

class TessellationApp(App):
    # 初始化着色器，vao vbo等
    def setupVertex(self) -> None:
        gl.glPatchParameteri(gl.GL_PATCH_VERTICES, 4)
        gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE)
        self.program = pygl.ProgramVFT("intermediate/shaders/tessellation.vs", 
                                      "intermediate/shaders/tessellation.fs",
                                      "intermediate/shaders/tessellation.tcs",
                                      "intermediate/shaders/tessellation.tes")
        self.background_color = glm.vec4(0.0, 0.0, 0.0, 1.0)
        vertices = np.array([
            0.4, -0.4, 0.5,
            -0.4, -0.4, 0.5,
            0.4,  0.4, 0.5,
            -0.4,  0.4, 0.5,
        ], dtype=gl.GLfloat)
        self.vao = pygl.VertexArrayObject()
        self.vbo = pygl.VertexBufferObject(vertices)
        binding_point = 0
        self.vao.setVertexBuffer(self.vbo, binding_point, 
                                 0, 3 * gl.sizeof(gl.GLfloat))
        attribute_position = pygl.VertexAttribute("position", 0, 3, 
                                                  gl.GL_FLOAT, False, 0)
        self.vao.setVertexAttribute(binding_point, attribute_position)
        self.single_outer = 1
        self.single_all = 1
        self.inner_level = [4.0, 4.0]
        self.outer_level = [4.0, 4.0, 4.0, 4.0]
        self.imgui_window_width = 220
        self.imgui_window_height = 320
        self.line_color = glm.vec3(1.0, 1.0, 1.0)


    # 配置imgui界面元素
    def showImGui(self)->None:
        imgui.begin("设置")
        _, color = imgui.color_edit3("背景颜色", self.background_color.x, 
                                     self.background_color.y, 
                                     self.background_color.z)
        self.background_color = glm.vec4(color[0], color[1], color[2], 1.0)
        _, color = imgui.color_edit3("线框颜色", self.line_color.x, 
                    self.line_color.y, self.line_color.z)
        self.line_color = glm.vec3(color[0], color[1], color[2])
        _, self.single_all = imgui.checkbox("内外统一细分层级", self.single_all)
        if self.single_all:
            _, self.inner_level[0] =  imgui.slider_int("层级", 
                                                    self.inner_level[0], 0, 10)
        else:
            _, self.inner_level[0] =  imgui.slider_int("内侧0", 
                                                    self.inner_level[0], 0, 10)
            _, self.inner_level[1] =  imgui.slider_int("内侧1", 
                                                    self.inner_level[1], 0, 10)
            imgui.dummy(0.0, 10.0)
            _, self.single_outer = imgui.checkbox("外侧统一细分层级", 
                                                    self.single_outer)
            if self.single_outer:
                _, self.outer_level[0] =  imgui.slider_int("外层级", 
                                                    self.outer_level[0], 0, 10)
            else:
                _, self.outer_level[0] = imgui.slider_int("外侧0", 
                                                    self.outer_level[0], 0, 10)
                _, self.outer_level[1] = imgui.slider_int("外侧1", 
                                                    self.outer_level[1], 0, 10)
                _, self.outer_level[2] = imgui.slider_int("外侧2", 
                                                    self.outer_level[2], 0, 10)
                _, self.outer_level[3] = imgui.slider_int("外侧3", 
                                                    self.outer_level[3], 0, 10)
        imgui.end()       

    # 渲染图形
    def render(self) -> None:
        gl.glClearNamedFramebufferfv(0, gl.GL_COLOR, 0, 
                                     self.background_color.to_tuple())
        self.program.use()
        self.vao.bind()
        self.program.setUniform1i(0, self.single_all)
        self.program.setUniform1i(1, self.single_outer)
        self.program.setUniform1fv(2, 2, self.inner_level)
        self.program.setUniform1fv(4, 4, self.outer_level)
        self.program.setUniform3fv(8, self.line_color)
        gl.glDrawArrays(gl.GL_PATCHES, 0, 4)

    # 释放资源
    def cleanup(self) -> None:
        self.vao.delete()
        self.vbo.delete()
        self.program.delete()

if __name__ == "__main__":
    app = TessellationApp(100, 100, 800, 600, "你好，曲面细分着色器App！")
    app.run()


